
package ltd.letao.mall.service.impl;

import ltd.letao.mall.common.*;
import ltd.letao.mall.controller.vo.*;
import ltd.letao.mall.dao.LeTaoMallGoodsMapper;
import ltd.letao.mall.dao.LeTaoMallOrderItemMapper;
import ltd.letao.mall.dao.LeTaoMallOrderMapper;
import ltd.letao.mall.dao.LeTaoMallShoppingCartItemMapper;
import ltd.letao.mall.entity.LeTaoMallGoods;
import ltd.letao.mall.entity.LeTaoMallOrder;
import ltd.letao.mall.entity.LeTaoMallOrderItem;
import ltd.letao.mall.entity.StockNumDTO;
import ltd.letao.mall.util.BeanUtil;
import ltd.letao.mall.util.NumberUtil;
import ltd.letao.mall.util.PageQueryUtil;
import ltd.letao.mall.util.PageResult;
import ltd.letao.mall.service.LeTaoMallOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

@Service
public class LeTaoMallOrderServiceImpl implements LeTaoMallOrderService {

    @Autowired
    private LeTaoMallOrderMapper leTaoMallOrderMapper;
    @Autowired
    private LeTaoMallOrderItemMapper leTaoMallOrderItemMapper;
    @Autowired
    private LeTaoMallShoppingCartItemMapper leTaoMallShoppingCartItemMapper;
    @Autowired
    private LeTaoMallGoodsMapper leTaoMallGoodsMapper;

    @Override
    public PageResult getLeTaoMallOrdersPage(PageQueryUtil pageUtil) {
        List<LeTaoMallOrder> leTaoMallOrders = leTaoMallOrderMapper.findLeTaoMallOrderList(pageUtil);
        int total = leTaoMallOrderMapper.getTotalLeTaoMallOrders(pageUtil);
        PageResult pageResult = new PageResult(leTaoMallOrders, total, pageUtil.getLimit(), pageUtil.getPage());
        return pageResult;
    }

    @Override
    @Transactional
    public String updateOrderInfo(LeTaoMallOrder leTaoMallOrder) {
        LeTaoMallOrder temp = leTaoMallOrderMapper.selectByPrimaryKey(leTaoMallOrder.getOrderId());
        //不为空且orderStatus>=0且状态为出库之前可以修改部分信息
        if (temp != null && temp.getOrderStatus() >= 0 && temp.getOrderStatus() < 3) {
            temp.setTotalPrice(leTaoMallOrder.getTotalPrice());
            temp.setUserAddress(leTaoMallOrder.getUserAddress());
            temp.setUpdateTime(new Date());
            if (leTaoMallOrderMapper.updateByPrimaryKeySelective(temp) > 0) {
                return ServiceResultEnum.SUCCESS.getResult();
            }
            return ServiceResultEnum.DB_ERROR.getResult();
        }
        return ServiceResultEnum.DATA_NOT_EXIST.getResult();
    }

    @Override
    @Transactional
    public String checkDone(Long[] ids) {
        //查询所有的订单 判断状态 修改状态和更新时间
        List<LeTaoMallOrder> orders = leTaoMallOrderMapper.selectByPrimaryKeys(Arrays.asList(ids));
        String errorOrderNos = "";
        if (!CollectionUtils.isEmpty(orders)) {
            for (LeTaoMallOrder leTaoMallOrder : orders) {
                if (leTaoMallOrder.getIsDeleted() == 1) {
                    errorOrderNos += leTaoMallOrder.getOrderNo() + " ";
                    continue;
                }
                if (leTaoMallOrder.getOrderStatus() != 1) {
                    errorOrderNos += leTaoMallOrder.getOrderNo() + " ";
                }
            }
            if (StringUtils.isEmpty(errorOrderNos)) {
                //订单状态正常 可以执行配货完成操作 修改订单状态和更新时间
                if (leTaoMallOrderMapper.checkDone(Arrays.asList(ids)) > 0) {
                    return ServiceResultEnum.SUCCESS.getResult();
                } else {
                    return ServiceResultEnum.DB_ERROR.getResult();
                }
            } else {
                //订单此时不可执行出库操作
                if (errorOrderNos.length() > 0 && errorOrderNos.length() < 100) {
                    return errorOrderNos + "订单的状态不是支付成功无法执行出库操作";
                } else {
                    return "你选择了太多状态不是支付成功的订单，无法执行配货完成操作";
                }
            }
        }
        //未查询到数据 返回错误提示
        return ServiceResultEnum.DATA_NOT_EXIST.getResult();
    }

    @Override
    @Transactional
    public String checkOut(Long[] ids) {
        //查询所有的订单 判断状态 修改状态和更新时间
        List<LeTaoMallOrder> orders = leTaoMallOrderMapper.selectByPrimaryKeys(Arrays.asList(ids));
        String errorOrderNos = "";
        if (!CollectionUtils.isEmpty(orders)) {
            for (LeTaoMallOrder leTaoMallOrder : orders) {
                if (leTaoMallOrder.getIsDeleted() == 1) {
                    errorOrderNos += leTaoMallOrder.getOrderNo() + " ";
                    continue;
                }
                if (leTaoMallOrder.getOrderStatus() != 1 && leTaoMallOrder.getOrderStatus() != 2) {
                    errorOrderNos += leTaoMallOrder.getOrderNo() + " ";
                }
            }
            if (StringUtils.isEmpty(errorOrderNos)) {
                //订单状态正常 可以执行出库操作 修改订单状态和更新时间
                if (leTaoMallOrderMapper.checkOut(Arrays.asList(ids)) > 0) {
                    return ServiceResultEnum.SUCCESS.getResult();
                } else {
                    return ServiceResultEnum.DB_ERROR.getResult();
                }
            } else {
                //订单此时不可执行出库操作
                if (errorOrderNos.length() > 0 && errorOrderNos.length() < 100) {
                    return errorOrderNos + "订单的状态不是支付成功或配货完成无法执行出库操作";
                } else {
                    return "你选择了太多状态不是支付成功或配货完成的订单，无法执行出库操作";
                }
            }
        }
        //未查询到数据 返回错误提示
        return ServiceResultEnum.DATA_NOT_EXIST.getResult();
    }

    @Override
    @Transactional
    public String closeOrder(Long[] ids) {
        //查询所有的订单 判断状态 修改状态和更新时间
        List<LeTaoMallOrder> orders = leTaoMallOrderMapper.selectByPrimaryKeys(Arrays.asList(ids));
        String errorOrderNos = "";
        if (!CollectionUtils.isEmpty(orders)) {
            for (LeTaoMallOrder leTaoMallOrder : orders) {
                // isDeleted=1 一定为已关闭订单
                if (leTaoMallOrder.getIsDeleted() == 1) {
                    errorOrderNos += leTaoMallOrder.getOrderNo() + " ";
                    continue;
                }
                //已关闭或者已完成无法关闭订单
                if (leTaoMallOrder.getOrderStatus() == 4 || leTaoMallOrder.getOrderStatus() < 0) {
                    errorOrderNos += leTaoMallOrder.getOrderNo() + " ";
                }
            }
            if (StringUtils.isEmpty(errorOrderNos)) {
                //订单状态正常 可以执行关闭操作 修改订单状态和更新时间
                if (leTaoMallOrderMapper.closeOrder(Arrays.asList(ids), LeTaoMallOrderStatusEnum.ORDER_CLOSED_BY_JUDGE.getOrderStatus()) > 0) {
                    return ServiceResultEnum.SUCCESS.getResult();
                } else {
                    return ServiceResultEnum.DB_ERROR.getResult();
                }
            } else {
                //订单此时不可执行关闭操作
                if (errorOrderNos.length() > 0 && errorOrderNos.length() < 100) {
                    return errorOrderNos + "订单不能执行关闭操作";
                } else {
                    return "你选择的订单不能执行关闭操作";
                }
            }
        }
        //未查询到数据 返回错误提示
        return ServiceResultEnum.DATA_NOT_EXIST.getResult();
    }

    @Override
    @Transactional
    public String saveOrder(LeTaoMallUserVO user, List<LeTaoMallShoppingCartItemVO> myShoppingCartItems) {
        List<Long> itemIdList = myShoppingCartItems.stream().map(LeTaoMallShoppingCartItemVO::getCartItemId).collect(Collectors.toList());
        List<Long> goodsIds = myShoppingCartItems.stream().map(LeTaoMallShoppingCartItemVO::getGoodsId).collect(Collectors.toList());
        List<LeTaoMallGoods> leTaoMallGoods = leTaoMallGoodsMapper.selectByPrimaryKeys(goodsIds);
        //检查是否包含已下架商品
        List<LeTaoMallGoods> goodsListNotSelling = leTaoMallGoods.stream()
                .filter(leTaoMallGoodsTemp -> leTaoMallGoodsTemp.getGoodsSellStatus() != Constants.SELL_STATUS_UP)
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(goodsListNotSelling)) {
            //goodsListNotSelling 对象非空则表示有下架商品
            LeTaoMallException.fail(goodsListNotSelling.get(0).getGoodsName() + "已下架，无法生成订单");
        }
        Map<Long, LeTaoMallGoods> leTaoMallGoodsMap = leTaoMallGoods.stream().collect(Collectors.toMap(LeTaoMallGoods::getGoodsId, Function.identity(), (entity1, entity2) -> entity1));
        //判断商品库存
        for (LeTaoMallShoppingCartItemVO shoppingCartItemVO : myShoppingCartItems) {
            //查出的商品中不存在购物车中的这条关联商品数据，直接返回错误提醒
            if (!leTaoMallGoodsMap.containsKey(shoppingCartItemVO.getGoodsId())) {
                LeTaoMallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
            }
            //存在数量大于库存的情况，直接返回错误提醒
            if (shoppingCartItemVO.getGoodsCount() > leTaoMallGoodsMap.get(shoppingCartItemVO.getGoodsId()).getStockNum()) {
                LeTaoMallException.fail(ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult());
            }
        }
        //删除购物项
        if (!CollectionUtils.isEmpty(itemIdList) && !CollectionUtils.isEmpty(goodsIds) && !CollectionUtils.isEmpty(leTaoMallGoods)) {
            if (leTaoMallShoppingCartItemMapper.deleteBatch(itemIdList) > 0) {
                List<StockNumDTO> stockNumDTOS = BeanUtil.copyList(myShoppingCartItems, StockNumDTO.class);
                int updateStockNumResult = leTaoMallGoodsMapper.updateStockNum(stockNumDTOS);
                if (updateStockNumResult < 1) {
                    LeTaoMallException.fail(ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult());
                }
                //生成订单号
                String orderNo = NumberUtil.genOrderNo();
                int priceTotal = 0;
                //保存订单
                LeTaoMallOrder leTaoMallOrder = new LeTaoMallOrder();
                leTaoMallOrder.setOrderNo(orderNo);
                leTaoMallOrder.setUserId(user.getUserId());
                leTaoMallOrder.setUserAddress(user.getAddress());
                //总价
                for (LeTaoMallShoppingCartItemVO leTaoMallShoppingCartItemVO : myShoppingCartItems) {
                    priceTotal += leTaoMallShoppingCartItemVO.getGoodsCount() * leTaoMallShoppingCartItemVO.getSellingPrice();
                }
                if (priceTotal < 1) {
                    LeTaoMallException.fail(ServiceResultEnum.ORDER_PRICE_ERROR.getResult());
                }
                leTaoMallOrder.setTotalPrice(priceTotal);
                //订单body字段，用来作为生成支付单描述信息，暂时未接入第三方支付接口，故该字段暂时设为空字符串
                String extraInfo = "";
                leTaoMallOrder.setExtraInfo(extraInfo);
                //生成订单项并保存订单项纪录
                if (leTaoMallOrderMapper.insertSelective(leTaoMallOrder) > 0) {
                    //生成所有的订单项快照，并保存至数据库
                    List<LeTaoMallOrderItem> leTaoMallOrderItems = new ArrayList<>();
                    for (LeTaoMallShoppingCartItemVO leTaoMallShoppingCartItemVO : myShoppingCartItems) {
                        LeTaoMallOrderItem leTaoMallOrderItem = new LeTaoMallOrderItem();
                        //使用BeanUtil工具类将leTaoMallShoppingCartItemVO中的属性复制到leTaoMallOrderItem对象中
                        BeanUtil.copyProperties(leTaoMallShoppingCartItemVO, leTaoMallOrderItem);
                        //LeTaoMallOrderMapper文件insert()方法中使用了useGeneratedKeys因此orderId可以获取到
                        leTaoMallOrderItem.setOrderId(leTaoMallOrder.getOrderId());
                        leTaoMallOrderItems.add(leTaoMallOrderItem);
                    }
                    //保存至数据库
                    if (leTaoMallOrderItemMapper.insertBatch(leTaoMallOrderItems) > 0) {
                        //所有操作成功后，将订单号返回，以供Controller方法跳转到订单详情
                        return orderNo;
                    }
                    LeTaoMallException.fail(ServiceResultEnum.ORDER_PRICE_ERROR.getResult());
                }
                LeTaoMallException.fail(ServiceResultEnum.DB_ERROR.getResult());
            }
            LeTaoMallException.fail(ServiceResultEnum.DB_ERROR.getResult());
        }
        LeTaoMallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
        return ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult();
    }

    @Override
    public LeTaoMallOrderDetailVO getOrderDetailByOrderNo(String orderNo, Long userId) {
        LeTaoMallOrder leTaoMallOrder = leTaoMallOrderMapper.selectByOrderNo(orderNo);
        if (leTaoMallOrder == null) {
            LeTaoMallException.fail(ServiceResultEnum.ORDER_NOT_EXIST_ERROR.getResult());
        }
        //验证是否是当前userId下的订单，否则报错
        if (!userId.equals(leTaoMallOrder.getUserId())) {
            LeTaoMallException.fail(ServiceResultEnum.NO_PERMISSION_ERROR.getResult());
        }
        List<LeTaoMallOrderItem> orderItems = leTaoMallOrderItemMapper.selectByOrderId(leTaoMallOrder.getOrderId());
        //获取订单项数据
        if (CollectionUtils.isEmpty(orderItems)) {
            LeTaoMallException.fail(ServiceResultEnum.ORDER_ITEM_NOT_EXIST_ERROR.getResult());
        }
        List<LeTaoMallOrderItemVO> leTaoMallOrderItemVOS = BeanUtil.copyList(orderItems, LeTaoMallOrderItemVO.class);
        LeTaoMallOrderDetailVO leTaoMallOrderDetailVO = new LeTaoMallOrderDetailVO();
        BeanUtil.copyProperties(leTaoMallOrder, leTaoMallOrderDetailVO);
        leTaoMallOrderDetailVO.setOrderStatusString(LeTaoMallOrderStatusEnum.getLeTaoMallOrderStatusEnumByStatus(leTaoMallOrderDetailVO.getOrderStatus()).getName());
        leTaoMallOrderDetailVO.setPayTypeString(PayTypeEnum.getPayTypeEnumByType(leTaoMallOrderDetailVO.getPayType()).getName());
        leTaoMallOrderDetailVO.setLeTaoMallOrderItemVOS(leTaoMallOrderItemVOS);
        return leTaoMallOrderDetailVO;
    }

    @Override
    public LeTaoMallOrder getLeTaoMallOrderByOrderNo(String orderNo) {
        return leTaoMallOrderMapper.selectByOrderNo(orderNo);
    }

    @Override
    public PageResult getMyOrders(PageQueryUtil pageUtil) {
        int total = leTaoMallOrderMapper.getTotalLeTaoMallOrders(pageUtil);
        List<LeTaoMallOrder> leTaoMallOrders = leTaoMallOrderMapper.findLeTaoMallOrderList(pageUtil);
        List<LeTaoMallOrderListVO> orderListVOS = new ArrayList<>();
        if (total > 0) {
            //数据转换 将实体类转成vo
            orderListVOS = BeanUtil.copyList(leTaoMallOrders, LeTaoMallOrderListVO.class);
            //设置订单状态中文显示值
            for (LeTaoMallOrderListVO leTaoMallOrderListVO : orderListVOS) {
                leTaoMallOrderListVO.setOrderStatusString(LeTaoMallOrderStatusEnum.getLeTaoMallOrderStatusEnumByStatus(leTaoMallOrderListVO.getOrderStatus()).getName());
            }
            List<Long> orderIds = leTaoMallOrders.stream().map(LeTaoMallOrder::getOrderId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(orderIds)) {
                List<LeTaoMallOrderItem> orderItems = leTaoMallOrderItemMapper.selectByOrderIds(orderIds);
                Map<Long, List<LeTaoMallOrderItem>> itemByOrderIdMap = orderItems.stream().collect(groupingBy(LeTaoMallOrderItem::getOrderId));
                for (LeTaoMallOrderListVO leTaoMallOrderListVO : orderListVOS) {
                    //封装每个订单列表对象的订单项数据
                    if (itemByOrderIdMap.containsKey(leTaoMallOrderListVO.getOrderId())) {
                        List<LeTaoMallOrderItem> orderItemListTemp = itemByOrderIdMap.get(leTaoMallOrderListVO.getOrderId());
                        //将LeTaoMallOrderItem对象列表转换成LeTaoMallOrderItemVO对象列表
                        List<LeTaoMallOrderItemVO> leTaoMallOrderItemVOS = BeanUtil.copyList(orderItemListTemp, LeTaoMallOrderItemVO.class);
                        leTaoMallOrderListVO.setLeTaoMallOrderItemVOS(leTaoMallOrderItemVOS);
                    }
                }
            }
        }
        PageResult pageResult = new PageResult(orderListVOS, total, pageUtil.getLimit(), pageUtil.getPage());
        return pageResult;
    }

    @Override
    public String cancelOrder(String orderNo, Long userId) {
        LeTaoMallOrder leTaoMallOrder = leTaoMallOrderMapper.selectByOrderNo(orderNo);
        if (leTaoMallOrder != null) {
            //验证是否是当前userId下的订单，否则报错
            if (!userId.equals(leTaoMallOrder.getUserId())) {
                LeTaoMallException.fail(ServiceResultEnum.NO_PERMISSION_ERROR.getResult());
            }
            //订单状态判断
            if (leTaoMallOrder.getOrderStatus().intValue() == LeTaoMallOrderStatusEnum.ORDER_SUCCESS.getOrderStatus()
                    || leTaoMallOrder.getOrderStatus().intValue() == LeTaoMallOrderStatusEnum.ORDER_CLOSED_BY_MALLUSER.getOrderStatus()
                    || leTaoMallOrder.getOrderStatus().intValue() == LeTaoMallOrderStatusEnum.ORDER_CLOSED_BY_EXPIRED.getOrderStatus()
                    || leTaoMallOrder.getOrderStatus().intValue() == LeTaoMallOrderStatusEnum.ORDER_CLOSED_BY_JUDGE.getOrderStatus()) {
                return ServiceResultEnum.ORDER_STATUS_ERROR.getResult();
            }
            if (leTaoMallOrderMapper.closeOrder(Collections.singletonList(leTaoMallOrder.getOrderId()), LeTaoMallOrderStatusEnum.ORDER_CLOSED_BY_MALLUSER.getOrderStatus()) > 0) {
                return ServiceResultEnum.SUCCESS.getResult();
            } else {
                return ServiceResultEnum.DB_ERROR.getResult();
            }
        }
        return ServiceResultEnum.ORDER_NOT_EXIST_ERROR.getResult();
    }

    @Override
    public String finishOrder(String orderNo, Long userId) {
        LeTaoMallOrder leTaoMallOrder = leTaoMallOrderMapper.selectByOrderNo(orderNo);
        if (leTaoMallOrder != null) {
            //验证是否是当前userId下的订单，否则报错
            if (!userId.equals(leTaoMallOrder.getUserId())) {
                return ServiceResultEnum.NO_PERMISSION_ERROR.getResult();
            }
            //订单状态判断 非出库状态下不进行修改操作
            if (leTaoMallOrder.getOrderStatus().intValue() != LeTaoMallOrderStatusEnum.ORDER_EXPRESS.getOrderStatus()) {
                return ServiceResultEnum.ORDER_STATUS_ERROR.getResult();
            }
            leTaoMallOrder.setOrderStatus((byte) LeTaoMallOrderStatusEnum.ORDER_SUCCESS.getOrderStatus());
            leTaoMallOrder.setUpdateTime(new Date());
            if (leTaoMallOrderMapper.updateByPrimaryKeySelective(leTaoMallOrder) > 0) {
                return ServiceResultEnum.SUCCESS.getResult();
            } else {
                return ServiceResultEnum.DB_ERROR.getResult();
            }
        }
        return ServiceResultEnum.ORDER_NOT_EXIST_ERROR.getResult();
    }

    @Override
    public String paySuccess(String orderNo, int payType) {
        LeTaoMallOrder leTaoMallOrder = leTaoMallOrderMapper.selectByOrderNo(orderNo);
        if (leTaoMallOrder != null) {
            //订单状态判断 非待支付状态下不进行修改操作
            if (leTaoMallOrder.getOrderStatus().intValue() != LeTaoMallOrderStatusEnum.ORDER_PRE_PAY.getOrderStatus()) {
                return ServiceResultEnum.ORDER_STATUS_ERROR.getResult();
            }
            leTaoMallOrder.setOrderStatus((byte) LeTaoMallOrderStatusEnum.ORDER_PAID.getOrderStatus());
            leTaoMallOrder.setPayType((byte) payType);
            leTaoMallOrder.setPayStatus((byte) PayStatusEnum.PAY_SUCCESS.getPayStatus());
            leTaoMallOrder.setPayTime(new Date());
            leTaoMallOrder.setUpdateTime(new Date());
            if (leTaoMallOrderMapper.updateByPrimaryKeySelective(leTaoMallOrder) > 0) {
                return ServiceResultEnum.SUCCESS.getResult();
            } else {
                return ServiceResultEnum.DB_ERROR.getResult();
            }
        }
        return ServiceResultEnum.ORDER_NOT_EXIST_ERROR.getResult();
    }

    @Override
    public List<LeTaoMallOrderItemVO> getOrderItems(Long id) {
        LeTaoMallOrder leTaoMallOrder = leTaoMallOrderMapper.selectByPrimaryKey(id);
        if (leTaoMallOrder != null) {
            List<LeTaoMallOrderItem> orderItems = leTaoMallOrderItemMapper.selectByOrderId(leTaoMallOrder.getOrderId());
            //获取订单项数据
            if (!CollectionUtils.isEmpty(orderItems)) {
                List<LeTaoMallOrderItemVO> leTaoMallOrderItemVOS = BeanUtil.copyList(orderItems, LeTaoMallOrderItemVO.class);
                return leTaoMallOrderItemVOS;
            }
        }
        return null;
    }
}